package com.polaris.live.utils.zego.media

import com.polaris.live.common.util.LogExt
import com.polaris.live.utils.zego.LiveEngineManage
import im.zego.zegoexpress.ZegoExpressEngine
import im.zego.zegoexpress.ZegoMediaPlayer
import im.zego.zegoexpress.callback.IZegoMediaPlayerEventHandler
import im.zego.zegoexpress.constants.ZegoMediaPlayerNetworkEvent
import im.zego.zegoexpress.constants.ZegoMediaPlayerState

/**
 * MediaPlayerUtils 本地音频播放器
 *
 * @author Created by 天晴 on 2024/9/14 15:51
 * @since 1.0.0
 */
class MediaPlayerUtils {

    val TAG = "MediaPlayerUtils"
    private var engine: ZegoExpressEngine? = null
    private var mediaplayer: ZegoMediaPlayer? = null

    init {
        createMediaPlayer()
    }

    private fun createMediaPlayer() {
        engine = LiveEngineManage.getEngine()
        mediaplayer = engine?.createMediaPlayer()
        if (mediaplayer != null) {
            LogExt.logI(TAG, "createMediaPlayer create sucess")
        } else {
            LogExt.logI(TAG, "createMediaPlayer create fail");
        }
        mediaplayer?.enableAux(true)

        mediaplayer?.setEventHandler(object : IZegoMediaPlayerEventHandler() {
            override fun onMediaPlayerStateUpdate(
                mediaPlayer: ZegoMediaPlayer,
                state: ZegoMediaPlayerState,
                errorCode: Int,
            ) {
                MediaProxy.handlerMediaPlayerStateUpdate(state, errorCode)
                // 本回调在 UI 线程被回调，开发者可以在此进行 UI 的变化，例如播放按钮的变化
                LogExt.logI(TAG) {
                    "onMediaPlayerStateUpdate: state = " + state.value() + ", errorCode = " + errorCode + ", zegoExpressMediaplayer = " + mediaPlayer
                }
            }

            override fun onMediaPlayerNetworkEvent(
                mediaPlayer: ZegoMediaPlayer,
                networkEvent: ZegoMediaPlayerNetworkEvent,
            ) {
                // 本回调在 UI 线程被回调，开发者可以在此进行 UI 的变化，例如网络不好的情况做友好的提示
                LogExt.logI(TAG) {
                    "onMediaPlayerNetworkEvent: networkEvent = " + networkEvent.value() + ", zegoExpressMediaplayer = " + mediaPlayer
                }
            }

            override fun onMediaPlayerPlayingProgress(mediaPlayer: ZegoMediaPlayer, millisecond: Long) {
                MediaProxy.handlerProgress(millisecond)
                // 本回调在 UI 线程被回调，开发者可以在此进行 UI 的变化，例如进度条的变化
                LogExt.logI(TAG) {
                    "onMediaPlayerPlayingProgress: millisecond = $millisecond, zegoExpressMediaplayer = $mediaPlayer"
                }
            }
        })
    }

    /**
     * 加载媒体资源
     *
     * 可传本地资源的绝对路径或者网络资源的 URL
     * @param path 本地资源路径或网络资源的 URL
     * @param callback 资源加载结果的通知
     */
    /**
     * 加载媒体资源
     *
     * 可传本地资源的绝对路径或者网络资源的 URL
     * @param path 本地资源路径或网络资源的 URL
     * @param callback 资源加载结果的通知
     */
    fun loadResource(path: String, success: () -> Unit, fail: () -> Unit) {
        mediaplayer?.loadResource(path) { errorCode -> // 本回调在 UI 线程被回调，开发者可以在此进行 UI 的变化
            if (errorCode == 0) {
                success.invoke()
                LogExt.logI(TAG, "onLoadResourceCallback: success")
            } else {
                fail.invoke()
                LogExt.logI(TAG, "onLoadResourceCallback: errorcode = $errorCode")
            }
        }
    }

    /**
     * 设置是否重复播放
     */
    fun enableRepeat(repeat: Boolean) {
        mediaplayer?.enableRepeat(repeat)
    }

    /**
     * 开始播放，播放前需要先加载资源
     */
    fun start() {
        mediaplayer?.start();
    }

    /**
     *  暂停播放
     */
    fun pause() {
        mediaplayer?.pause();
    }

    /**
     *  恢复播放
     */
    fun resume() {
        mediaplayer?.resume();
    }

    /**
     *  停止播放
     */
    fun stop() {
        mediaplayer?.stop();
    }

    /**
     * 播放进度控制
     */
    fun seekTo(progress: Long) {
        mediaplayer?.seekTo(progress) { errorcode -> // 本回调在UI线程被回调，开发者可以在此进行UI的变化
            if (errorcode == 0) {
                LogExt.logI(TAG, "onSeekToTimeCallback: success")
            } else {
                LogExt.logI(TAG, "onSeekToTimeCallback: errorcode = $errorcode")
            }
        }
    }

    /**
     * 播放速度控制
     *  必须在加载资源完成后才能调用, 播放速度范围为 0.3 ~ 4.0，默认为 1.0
     */
    fun setPlaySpeed(speed: Float) {
        mediaplayer?.setPlaySpeed(speed)
    }

    /**
     * 控制本地静音播放
     */
    fun muteLocal(mute: Boolean) {
        mediaplayer?.muteLocal(mute)

    }

    /**
     * 将文件的声音混入正在推的流中
     */
    fun enableAux(aux: Boolean) {
        mediaplayer?.enableAux(aux)
    }

    /**
     * 获取播放音量
     */
    fun getPlayVolume(): Int {
        return mediaplayer?.playVolume ?: 0
    }

    /**
     * 获取推流音量
     */
    fun getPublishVolume(): Int {
        return mediaplayer?.publishVolume ?: 0
    }

    /**
     * 控制播放音量
     */
    fun setPlayVolume(volume: Int) {
        mediaplayer?.playVolume = volume
    }

    /**
     * 控制推流音量
     */
    fun setPublishVolume(volume: Int) {
        mediaplayer?.publishVolume = volume
    }

    /**
     * 获取当前播放进度
     */
    fun getCurrentProgress(): Long {
        return mediaplayer?.currentProgress ?: 0L
    }

    /**
     * 切換播放文件
     */
    fun switchAudio(path: String) {
        stop()
        loadResource(path, success = {}, fail = {})
    }

    fun destroyMediaPlayer() {
        mediaplayer?.stop()
        // 销毁媒体播放器实例对象
        engine?.destroyMediaPlayer(mediaplayer)
        // 在调用接口销毁的时候，为避免内存泄漏，开发者须自己手动释放业务层所持有的引用
        mediaplayer = null
        engine = null
    }
}